﻿using System.Linq.Expressions;
using Gateway.Common.Entity;
using Microsoft.EntityFrameworkCore;

namespace Gateway.IRepositories
{
    public interface IAppRepository<TEntity> where TEntity : class, IEntityBase
    {
        public DbSet<TEntity> Entities { get; }
        #region Select

        /// <summary>
        /// Gets an entity with given primary key.
        /// </summary>
        /// <param name="id">Primary key of the entity to get</param>
        /// <returns>Entity</returns>
        Task<TEntity> GetAsync(string id);

        Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// Gets an entity with given given predicate or null if not found.
        /// </summary>
        /// <param name="predicate">Predicate to filter entities</param>
        Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// 查询数量
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<long> CountAsync(Expression<Func<TEntity, bool>> predicate);

        Task<bool> AnyAsync(Expression<Func<TEntity, bool>> predicate);

        #endregion

        #region Insert

        /// <summary>
        /// Inserts a new entity.
        /// </summary>
        /// <param name="entity">Inserted entity</param>
        Task AddAsync(TEntity entity);

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task AddRangeAsync(IEnumerable<TEntity> entity);

        #endregion Insert

        #region Update

        /// <summary>
        /// Updates an existing entity. 
        /// </summary>
        /// <param name="entity">Entity</param>
        Task UpdateAsync(TEntity entity);

        Task UpdateRangeAsync(IEnumerable<TEntity> entity);

        #endregion Update

        #region Delete

        /// <summary>
        /// Deletes an entity.
        /// </summary>
        /// <param name="entity">Entity to be deleted</param>
        Task DeleteAsync(TEntity entity);

        /// <summary>
        /// Deletes an entity by primary key.
        /// </summary>
        /// <param name="id">Primary key of the entity</param>
        Task DeleteAsync(string id);

        /// <summary>
        /// Deletes many entities by function.
        /// Notice that: All entities fits to given predicate are retrieved and deleted.
        /// This may cause major performance problems if there are too many entities with
        /// given predicate.
        /// </summary>
        /// <param name="predicate">A condition to filter entities</param>
        Task DeleteAsync(Expression<Func<TEntity, bool>> predicate);

        Task DeleteRangeAsync(Expression<Func<TEntity, bool>> predicate);
        #endregion


        #region bulk 批量操作

        /// <summary>
        /// 批量插入操作
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task BulkInsert(List<TEntity> entities);

        /// <summary>
        /// 批量插入操作
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        Task BulkUpdate(List<TEntity> entities);

        #endregion
    }
}